package cc.avatar.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class ScriptRunner {

    private ArrayList<String> command = null;
    private String osName;

    private void init() {
        command = new ArrayList<String>();
        osName = System.getProperty("os.name");
        if (osName.indexOf("Windows") != -1) {
            if (osName.indexOf("95") != -1) {
                command.add("command.com");
            } else {
                command.add("cmd.exe");
            }
            command.add("/C");
        } else {
            command.add("sh");
        }
    }

    public void executeScript(String script, String parameters) {

        StringTokenizer st = new StringTokenizer(script, "\n");
        while (st.hasMoreTokens()) {
            String comm = st.nextToken();
            if (comm.trim().length() == 0)
                continue;

            init();
            if (osName.indexOf("Windows") != -1) {
                command.add(comm + " " + parameters);
                processCommandWithoutWait(command);
            } else {
                command.add(comm);
                command.add(parameters);
                processCommandWithoutWait(command);
            }

        }
    }

    public boolean executeScript(String[] scripts) {
        for (int i = 0; i < scripts.length; i++) {
            String parameter = scripts[i];
            if (parameter.trim().length() == 0)
                continue;
            init();
            command.add(parameter);
            return processCommand(command);
        }
        return false;
    }

    private boolean processCommand(ArrayList<String> commands){
        String[] cmd = new String[commands.size()];
        for (int n = 0; n < commands.size(); n++)
            cmd[n] = commands.get(n);
        try {
            Process proc = Runtime.getRuntime().exec(cmd);
            StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(),
                    "Error");
            StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(),
                    "Output");
            errorGobbler.start();
            outputGobbler.start();
        
            int exitVal = proc.waitFor();
            if (exitVal != 0) {
                proc.destroy();
                return false;
            }

            return true;
            
        } catch (InterruptedException e) {        
            return false;
        } catch (IOException e) {          
            return false;
        }
    }
    
    private void processCommandWithoutWait(ArrayList<String> commands){
        String[] cmd = new String[commands.size()];
        for (int n = 0; n < commands.size(); n++)
            cmd[n] = commands.get(n);
        try {
            Process proc = Runtime.getRuntime().exec(cmd);
            StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(),
                    "Error");
            StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(),
                    "Output");
            errorGobbler.start();
            outputGobbler.start();                     
        } catch (IOException e) {
            System.out.println("Error occurs during running script: " + e.getMessage());            
        }
    }
 

    class StreamGobbler extends Thread {
        private InputStream is;
        private String type;

        StreamGobbler(InputStream is, String type) {
            this.is = is;
            this.type = type;
        }

        public void run() {
            try {
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader br = new BufferedReader(isr);
                String line = null;
                while ((line = br.readLine()) != null) {
                    if (type.equals("Error")){
                    	System.out.println("Error:" + line);
                    } else {
                    	System.out.println("Debug:" + line);
                    }
                }
            } catch (IOException ioe) {
            	System.out.println(ioe.getMessage());
                ioe.printStackTrace();
            }
        }

        public InputStream getIs() {
            return is;
        }

        public void setIs(InputStream is) {
            this.is = is;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }
    }
}
